<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport" />
    <title>Chat-GPT-3</title>
    <link rel="shortcut icon" href="./img/snoopy-head.ico" type="image/x-icon">
    <script src="./js/axios.min.js"></script>
    <script src="./js/particles.min.js"></script>
</head>

<body>
    <div id="particles-js"></div>
    <style type="text/css">
        #particles-js {
            z-index: 0;
            position: absolute;
            top: 0;
            height: 100%;
            width: 100%;
            background: #2c3e50;
        }
    </style>


    <div id="app">
        <div class="title">ChatGPT3 </div>
        <div class="showbox">
            <textarea id="res"
                placeholder="欢迎使用ChatGPT智能AI客服,本项目基于GPT-3接口开发,能够实现与ChatGPT类似的持续性对话功能,AI将记忆并结合语境对话。"></textarea>
        </div>
        <div class="promptText">请输入需要查询的内容：(使用/help指令获取更多帮助) </div>
        <div class="inputbox">
            <textarea id="inputbox" autofocus required type="text" cols="100" rows="2" onkeydown="handleKeyPress(event)"
                placeholder="请在这里输入你想要提问的内容"></textarea>
        </div>
        <div class="sendbox"><button onclick="ask()">发送</button></div>
    </div>
</body>
<script>window.apikey = "";
    window.prompt1 = "";
    window.mt = 2048;
    window.tpr = 0.9;
    window.tp = 1;
    window.fp = 0;
    window.pp = 0;
    window.mode = "true";
    window.csize = 1000;
    const textarea = window.document.getElementById("res");
    const inputbox = window.document.getElementById("inputbox");
    var histories = "";
    // addText("欢迎使用ChatGPT智能AI客服,本项目基于GPT-3接口开发,能够实现与ChatGPT类似的持续性对话功能,AI将记忆并结合语境对话。");

    if (getCookie("apikey") != undefined && getCookie("apikey") != "") {
        window.apikey = getCookie("apikey");
    }

    else {
        window.apikey = prompt("请在输入框内输入并提交您从官方网站获取的apikey:");
        setCookie("apikey", window.apikey);
    }

    if (getCookie("prompt1") != undefined) {
        window.prompt1 = getCookie("prompt1");
    }

    if (getCookie("mt") != undefined) {
        window.mt = Number(getCookie("mt"));
    }

    if (getCookie("tpr") != undefined) {
        window.tpr = Number(getCookie("tpr"));
    }

    if (getCookie("tp") != undefined) {
        window.tp = Number(getCookie("tp"));
    }

    if (getCookie("fp") != undefined) {
        window.fp = Number(getCookie("fp"));
    }

    if (getCookie("pp") != undefined) {
        window.pp = Number(getCookie("pp"));
    }

    if (getCookie("mode") != undefined) {
        window.mode = getCookie("mode");
    }

    if (getCookie("csize") != undefined) {
        window.csize = Number(getCookie("csize"));
    }

    function ask() {
        let intputtext = inputbox.value;

        if (intputtext.startsWith("/")) {
            intputtext = intputtext.substring(1);

            switch (intputtext) {
                case "help":
                    addText("请输入以下指令来更改ChatGPT的参数:\n\n" + "/apikey  (用于设置apikey,只有在官网注册获取apikey才能正常使用本服务)\n" + "/prompt  (为每次发送的文本添加前置上下文)\n" + "/maxtoken  (用于控制ChatGPT每次能生成的词数.)\n" + "/tpr (可以用来控制ChatGPT生成的话的多样性)\n" + "/top  (可以用来控制ChatGPT生成的话的质量)\n" + "/fp  (可以用来控制ChatGPT生成的话的“新颖程度”)\n" + "/pp  (用于控制ChatGPT产生的句子的长度)\n" + "/info  (用于显示当前各项参数的值)\n" + "/mode  (用于设置是否启用持续对话模式)\n" + "/csize  (用于设置每次发送给API接口的字符数)\n" + "/save  (用于将设置的参数保存到浏览器的Cookie,有效期30天)");
                    break;
                case "info": addText("当前的各项参数:\n\n" + "apikey:" + window.apikey + "\n\n" + "Prompt:" + window.prompt1 + "\n\n" + "Max_tokens:" + window.mt + "\n" + "Temperature:" + window.tpr + "\n" + "Top_p:" + window.tp + "\n" + "Frequency_penalty:" + window.fp + "\n" + "Presence_penalty:" + window.pp + "\n" + "mode:" + window.mode + "\n" + "csize:" + window.csize);
                    break;
                case "save":
                    setCookie("apikey", window.apikey);
                    setCookie("prompt1", window.prompt1);
                    setCookie("mt", window.mt);
                    setCookie("tpr", window.tpr);
                    setCookie("tp", window.tp);
                    setCookie("fp", window.fp);
                    setCookie("pp", window.pp);
                    setCookie("mode", window.mode);
                    setCookie("csize", window.csize);
                    addText("参数保存成功,数据将保存30天");
                    break;
                case "apikey": window.apikey = prompt("apikey 请输入从官网获取到的apikey,默认为空");
                    addText("设置成功");
                    break;
                case "prompt": window.prompt1 = prompt("Prompt 请输入要添加的上下文文本,默认为空");
                    addText("设置成功");
                    break;
                case "maxtoken": window.mt = Number(prompt("Max_tokens 请输入ChatGPT每次能生成的词数,默认为2048"));
                    addText("设置成功");
                    break;
                case "tpr": window.tpr = Number(prompt("Temperature 请输入一个0到1.0的一位小数,默认为1.0"));
                    addText("设置成功");
                    break;
                case "top": window.tp = Number(prompt("Top_p 请输入一个0到1.0的一位小数,默认为1.0"));
                    addText("设置成功");
                    break;
                case "fp": window.fp = Number(prompt("Frequency_penalty 请输入一个-2.0到2.0的一位小数,默认为0"));
                    addText("设置成功");
                    break;
                case "pp": window.pp = Number(prompt("Presence_penalty 请输入一个-2.0到2.0的一位小数,默认为0"));
                    addText("设置成功");
                    break;
                case "mode": window.mode = prompt("mode 输入“true”开启持续对话模式,输入“false”关闭该模式,默认为“true”");
                    addText("设置成功");
                    break;
                case "csize": window.csize = prompt("csize 输入一个0到1000的整数,默认为1000");
                    addText("设置成功");
                    break;
                default: alert("未知指令");
            }

            inputbox.value = "";
            return;
        }

        if (window.mode == "false") {
            histories = [];
        }

        histories += "\n" + window.prompt1 + "\nQ:" + intputtext + "。";
        let question = "";

        if (histories.length <= window.csize) {
            question = histories;
        }

        else {
            question = histories.substring(histories.length - window.csize)
        }

        console.log(question);
        addText("我说：\n\n" + intputtext);
        textarea.value += '\n正在请求数据......';
        textarea.scrollTop = textarea.scrollHeight;

        axios.post('https://api.openai.com/v1/completions', {
            prompt: question, max_tokens: window.mt, model: "text-davinci-003", temperature: window.tpr,
            top_p: window.tp, frequency_penalty: window.fp, presence_penalty: window.pp
        }

            , {
                headers: {
                    'content-type': 'application/json', 'Authorization': 'Bearer ' + window.apikey
                }

            }).then(response => {
                let arr = textarea.value.split("\n");
                arr = arr.slice(0, arr.length - 1);
                textarea.value = arr.join("\n");
                let result = response.data.choices[0].text;
                histories += "\n" + result;
                let result1 = result;
                addText("AI说:\n" + result1.replace('A:', '').replace('A：', ''));
                inputbox.value = "";

            }).catch(error => {
                console.log(error);
                alert("服务器报错:\n" + error);
            });
    }

    function addText(text) {
        textarea.value += "\n" + text + "\n" + "————————————————————";
        textarea.scrollTop = textarea.scrollHeight;
    }

    // 添加cookie
    function setCookie(name, value) {
        let days = 10;
        var expires = '';

        if (days) {
            var date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            expires = '; expires=' + date.toUTCString();
        }

        document.cookie = name + '=' + (value || '') + expires + '; path=/';
    }

    // 读取cookie
    function getCookie(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');

        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
        }

        return null;
    }


    // 按键事件
    function handleKeyPress(event) {
        if (event.keyCode === 13 && event.ctrlKey) {
            // Enter键被按下，且同时按下了Ctrl键
            ask();
            // 将textarea中的内容清空
            event.target.value = '';
            event.preventDefault(); // 防止textarea元素换行
        }
    }

    particlesJS('particles-js',

        {
            "particles": {
                "number": {
                    "value": 60,
                    "density": {
                        "enable": true,
                        "value_area": 600
                    }
                },
                "color": {
                    "value": "#ffffff"
                },
                "shape": {
                    "type": "edge",
                    "stroke": {
                        "width": 0,
                        "color": "#6dedff"
                    },
                    "polygon": {
                        "nb_sides": 5
                    },
                    "image": {
                        "src": "img/github.svg",
                        "width": 100,
                        "height": 100
                    }
                },
                "opacity": {
                    "value": 0.5,
                    "random": 1,
                    "anim": {
                        "enable": false,
                        "speed": 1,
                        "opacity_min": 0.1,
                        "sync": false
                    }
                },
                "size": {
                    "value": 3,
                    "random": true,
                    "anim": {
                        "enable": false,
                        "speed": 10,
                        "size_min": 0.1,
                        "sync": false
                    }
                },
                "line_linked": {
                    "enable": true,
                    "distance": 150,
                    "color": "#6dedff",
                    "opacity": 0.4,
                    "width": 1
                },
                "move": {
                    "enable": true,
                    "speed": 3,
                    "direction": "none",
                    "random": true,
                    "straight": true,
                    "out_mode": "out",
                    "attract": {
                        "enable": 1,
                        "rotateX": 600,
                        "rotateY": 1200
                    }
                }
            },
            "interactivity": {
                "detect_on": "canvas",
                "events": {
                    "onhover": {
                        "enable": true,
                        "mode": "grab"
                    },
                    "onclick": {
                        "enable": true,
                        "mode": "push"
                    },
                    "resize": true
                },
                "modes": {
                    "grab": {
                        "distance": 200,
                        "line_linked": {
                            "opacity": 0.75
                        }
                    },
                    "bubble": {
                        "distance": 400,
                        "size": 40,
                        "duration": 2,
                        "opacity": 8,
                        "speed": 3
                    },
                    "repulse": {
                        "distance": 200
                    },
                    "push": {
                        "particles_nb": 4
                    },
                    "remove": {
                        "particles_nb": 2
                    }
                }
            },
            "retina_detect": true,
            "config_demo": {
                "hide_card": false,
                "background_color": "#2c3e50",
                "background_image": "",
                "background_position": "50% 50%",
                "background_repeat": "no-repeat",
                "background_size": "cover"
            }
        }

    )

</script>




<style>
    body {
        margin: 0px;
        padding: 0px;
        background-color: #343541;
        font-family: Arial, sans-serif;
        display: flex;
        align-items: center;
        justify-content: center;
        height: 100vh;
        /* 使body铺满整个屏幕 */
    }

    #app {
        z-index: 1;
        width: 70%;
        margin: 0 auto;
        background-color: white;
        border-radius: 5px;
        box-shadow: 0px 0px 5px #888;
        padding: 20px;
    }

    .title {
        text-align: center;
        font-size: 30px;
        font-weight: bold;
        margin-bottom: 20px;
    }

    .showbox {
        width: 100%;
        height: 400px;
        /* overflow: auto; */
        border: 2px solid #ccc;
        border-radius: 5px;
        padding: 0px;
        margin-bottom: 20px;
    }

    #res {
        width: 98%;
        height: 98%;
        border: none;
        resize: none;
        font-size: 15px;
    }

    .promptText {
        font-size: 18px;
        font-weight: bold;
        margin-bottom: 10px;
    }

    #inputbox {
        width: 100%;
        margin-bottom: 20px;
        height: 60px;
        border: 1px solid #ccc;
        border-radius: 5px;
        padding-top: 10px;
        font-size: 16px;
        resize: vertical;
    }

    .sendbox {
        text-align: center;
    }

    button {
        padding: 10px 60px;
        background-color: #4CAF50;
        color: white;
        border: none;
        border-radius: 5px;
        font-size: 18px;
        cursor: pointer;
        transition: background-color 0.3s;
    }

    button:hover {
        background-color: #3e8e41;
    }
</style>



</html>